'''
Author: kkk 997610780@qq.com
Date: 2025-03-12 10:02:38
LastEditors: kkk 997610780@qq.com
LastEditTime: 2025-03-12 17:19:53
FilePath: \\get-video-images\\markdown2excel.py
Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
'''
from io import BytesIO
import pandas as pd
from openpyxl import Workbook
from openpyxl.styles import Font
from markdown_it import MarkdownIt
import re
import os
import sys
import uuid
import datetime
import base64

# 删除未使用的导入
# sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# from coze_upload import upload_file_to_coze

def file_to_base64(file_path: str) -> str:
    """
    将文件转换为 Base64 编码字符串
    
    参数:
        file_path: 文件路径
        
    返回:
        str: Base64 编码的字符串
    """
    if not os.path.exists(file_path):
        raise FileNotFoundError(f"文件不存在: {file_path}")
    
    with open(file_path, "rb") as file:
        file_content = file.read()
        base64_encoded = base64.b64encode(file_content).decode('utf-8')
        return base64_encoded

def parse_markdown_table(markdown_content: str) -> tuple:
    """
    解析 Markdown 表格内容，提取表头和数据行
    
    参数:
        markdown_content: Markdown 表格内容
        
    返回:
        tuple: (headers, rows) 表头和数据行
    """
    headers = []
    rows = []
    
    # 按行分割 Markdown 内容
    lines = markdown_content.strip().split('\n')
    
    # 提取表头
    if lines and '|' in lines[0]:
        headers = [cell.strip() for cell in lines[0].split('|')]
        headers = [h for h in headers if h]  # 移除空单元格
    
    # 跳过分隔行 (---|---)
    start_idx = 2 if len(lines) > 1 else 1
    
    # 提取数据行
    for i in range(start_idx, len(lines)):
        if '|' in lines[i]:
            cells = [cell.strip() for cell in lines[i].split('|')]
            cells = [c for c in cells if c != '']  # 移除空单元格
            rows.append(cells)
            
    return headers, rows

def create_excel_workbook(headers: list, rows: list) -> Workbook:
    """
    创建 Excel 工作簿并填充数据
    
    参数:
        headers: 表头列表
        rows: 数据行列表
        
    返回:
        Workbook: 创建好的 Excel 工作簿
    """
    # 创建 Excel 工作簿
    wb = Workbook()
    ws = wb.active
    ws.title = "Markdown转Excel"
    
    # 写入表头
    for col_num, value in enumerate(headers, 1):
        ws.cell(row=1, column=col_num, value=value)
    
    # 处理数据行
    for row_idx, row_data in enumerate(rows, 2):
        for col_idx, cell_value in enumerate(row_data, 1):
            # 检查是否为图片链接
            img_match = re.search(r'!\[(.*?)\]\((.*?)\)', cell_value)
            if img_match:
                img_url = img_match.group(2)
                # 先创建单元格，然后设置超链接
                cell = ws.cell(row=row_idx, column=col_idx, value=f"点击查看图片")
                cell.hyperlink = img_url
            else:
                ws.cell(row=row_idx, column=col_idx, value=cell_value)
    
    # 自动调整列宽
    for col in ws.columns:
        max_length = 0
        for cell in col:
            if cell.value:
                max_length = max(max_length, len(str(cell.value)))
        ws.column_dimensions[col[0].column_letter].width = max(15, max_length + 2)
    
    return wb

def workbook_to_binary(wb: Workbook) -> bytes:
    """
    将 Excel 工作簿转换为二进制数据
    
    参数:
        wb: Excel 工作簿
        
    返回:
        bytes: 二进制数据
    """
    excel_binary = BytesIO()
    wb.save(excel_binary)
    excel_binary.seek(0)
    return excel_binary.getvalue()

def binary_to_base64(binary_data: bytes) -> str:
    """
    将二进制数据转换为 Base64 编码
    
    参数:
        binary_data: 二进制数据
        
    返回:
        str: Base64 编码字符串
    """
    try:
        base64_data = base64.b64encode(binary_data).decode('utf-8')
        print(f"✅ 数据已转换为 Base64，长度：{len(base64_data)} 字符")
        return base64_data
    except Exception as e:
        print(f"❌ 转换为 Base64 时出错：{str(e)}")
        return None

def base64_to_binary(base64_data: str) -> bytes:
    """
    将 Base64 编码的数据转换为二进制数据
    
    参数:
        base64_data: Base64 编码的字符串
        
    返回:
        bytes: 解码后的二进制数据
    """
    if not base64_data:
        print("❌ 输入的 Base64 数据为空")
        return None
    
    # 检查输入是否为有效的 Base64 字符串
    try:
        # 移除可能存在的 data URI 前缀
        if "base64," in base64_data:
            # 提取实际的 Base64 部分
            base64_data = base64_data.split("base64,")[1]
        
        # 确保字符串长度是 4 的倍数，如果不是，添加适当的填充
        padding_needed = len(base64_data) % 4
        if padding_needed:
            base64_data += "=" * (4 - padding_needed)
        
        # 尝试解码
        binary_data = base64.b64decode(base64_data)
        print(f"✅ Base64 数据已转换为二进制，大小：{len(binary_data)} 字节")
        return binary_data
    except Exception as e:
        print(f"❌ 从 Base64 转换为二进制时出错：{str(e)}")
        print(f"❌ Base64 数据长度：{len(base64_data) if base64_data else 0}")
        print(f"❌ Base64 数据前20个字符：{base64_data[:20] if base64_data and len(base64_data) > 20 else base64_data}")
        return None

def save_binary_to_file(binary_data: bytes, output_path: str) -> bool:
    """
    将二进制数据保存到文件
    
    参数:
        binary_data: 二进制数据
        output_path: 输出文件路径
        
    返回:
        bool: 是否保存成功
    """
    try:
        with open(output_path, 'wb') as f:
            f.write(binary_data)
        print(f"✅ 文件已生成：{output_path}")
        return True
    except Exception as e:
        print(f"❌ 保存文件时出错：{str(e)}")
        return False

def markdown_to_excel(markdown_content: str, output_path: str = None, convert_to_base64: bool = False) -> dict:
    """
    将 Markdown 表格转换为 Excel 文件
    
    参数:
        markdown_content: Markdown 表格内容
        output_path: 输出 Excel 文件路径，如果为None则不保存到本地
        convert_to_base64: 是否将生成的文件转换为 Base64
        
    返回:
        dict: 包含二进制内容或Base64编码的字典
    """
    # 解析 Markdown 表格
    headers, rows = parse_markdown_table(markdown_content)
    
    # 创建 Excel 工作簿
    wb = create_excel_workbook(headers, rows)
    
    # 转换为二进制数据
    binary_data = workbook_to_binary(wb)
    
    # 准备返回结果
    result = {"binary_data": binary_data}
    
    # 如果需要保存到文件
    if output_path:
        if save_binary_to_file(binary_data, output_path):
            result["file_path"] = output_path
    else:
        print("✅ Excel文件已生成在内存中")
    
    # 如果需要转换为 Base64
    if convert_to_base64:
        base64_data = binary_to_base64(binary_data)
        if base64_data:
            result["base64_data"] = base64_data
    
    return result

def generate_download_markdown(base64_data: str, output_markdown_path: str = None) -> str:
    """
    生成包含下载链接的Markdown内容，使用随机生成的文件名
    
    参数:
        base64_data: Base64编码的文件数据
        output_markdown_path: Markdown文件输出路径，如果为None则不保存文件
        
    返回:
        str: 生成的Markdown内容
    """
    # 生成随机文件名：时间戳_UUID.xlsx
    timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    random_id = str(uuid.uuid4())[:8]  # 使用UUID的前8位
    random_filename = f"excel_{timestamp}_{random_id}.xlsx"
    
    # 创建Markdown格式的下载链接
    markdown_content = f"""# Excel文件下载

[点击下载Excel文件](data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,{base64_data} "下载Excel文件")

> 文件名: {random_filename}  
> 生成时间: {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
"""
    
    # 如果指定了输出路径，保存Markdown文件
    if output_markdown_path:
        with open(output_markdown_path, "w", encoding="utf-8") as f:
            f.write(markdown_content)
        print(f"✅ Markdown下载页面已生成：{output_markdown_path}")
        print(f"✅ 随机生成的下载文件名：{random_filename}")
    
    return markdown_content


def html_to_markdown_download(base64_data: str) -> str:
    """
    将 HTML 下载页面转换为 Markdown 格式
    
    参数:
        base64_data: Base64编码的文件数据
        
    返回:
        str: Markdown 格式的下载内容
    """
    # 生成随机文件名：时间戳_UUID.xlsx
    timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    random_id = str(uuid.uuid4())[:8]
    random_filename = f"excel_{timestamp}_{random_id}.xlsx"
    
    # 创建 Markdown 格式的下载链接
    markdown_content = f"""# Excel 文件下载

## 文件信息
- 文件名：{random_filename}
- 生成时间：{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}

## 下载链接
[点击此处下载 Excel 文件](data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,{base64_data})

> 提示：点击链接后将自动下载文件
"""
    
    return markdown_content


def generate_download_html(base64_data: str, output_html_path: str = None) -> str:
    """
    生成包含下载链接的HTML页面，使用随机生成的文件名
    
    参数:
        base64_data: Base64编码的文件数据
        output_html_path: HTML文件输出路径，如果为None则不保存文件
        
    返回:
        str: 生成的HTML内容
    """
    # 生成随机文件名：时间戳_UUID.xlsx
    timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    random_id = str(uuid.uuid4())[:8]  # 使用UUID的前8位
    random_filename = f"excel_{timestamp}_{random_id}.xlsx"
    
    # 简化的HTML结构，只包含下载链接
    html_content = f"""<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>文件下载</title>

</head>
<body>
    <a  href="data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,{base64_data}" download="{random_filename}">
        下载文件
    </a>
</body>
</html>"""
    
    # 如果指定了输出路径，保存HTML文件
    if output_html_path:
        with open(output_html_path, "w", encoding="utf-8") as f:
            f.write(html_content)
        print(f"✅ HTML下载页面已生成：{output_html_path}")
        print(f"✅ 随机生成的下载文件名：{random_filename}")
    
    return html_content

# 使用示例
if __name__ == "__main__":
    markdown_content = f"|图片|时段|场景|景别|角色描述|台词/字幕|画面描述|商品描述|\n | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | \n | ![](https://p9-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/ac51af6a36cc46ac832550672a2bd5f7.jpg~tplv-mdko3gqilj-image.image?rk3s=81d4c505&x-expires=1772705165&x-signature=MQAhrHXd4tqE87mbZ6MYembQyFo%3D&x-wf-file_name=image4.jpg) | 1 | 机场候机厅 | 中景 | 一位孕妇在孕初期有孕吐反应，旁边有一位男士在照顾她 | 孕初期<br>aticaly 小鱼到了孕晚期胃口这么好<br>孕晚期<br>好好吃！<br>好吃吗 | 图中展示了孕妇在孕初期在机场候机厅孕吐的场景，以及孕晚期在餐桌前胃口大开的场景 | 无 | \n | ![](https://p3-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/6e4dabeb08f94685897d0aba5662ec0e.jpg~tplv-mdko3gqilj-image.image?rk3s=81d4c505&x-expires=1772705165&x-signature=nGxeNlqxWHcIt8miqePF%2BmfGSCY%3D&x-wf-file_name=image5.jpg) | 2 | 室内 | 特写 | 无 | 袋鼠妈妈他们家的 | 一只手拿着两支袋鼠妈妈品牌的牙膏，背景有一些装饰物品 | 袋鼠妈妈品牌的牙膏，有两种口味，分别是鲜橙味和蓝莓味，每支含量100g | \n | ![](undefined) | 3 | 室内 | 特写 | 无 | 孕产妇专用牙膏 | 一只手拿着一支袋鼠妈妈品牌的牙膏，下方是孕妇的肚子 | 袋鼠妈妈品牌的孕产妇专用牙膏，有鲜橙味和蓝莓味两种口味，每支含量100g | \n"

    # 生成随机文件名：时间戳_UUID.xlsx
    timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    random_id = str(uuid.uuid4())[:8]  # 使用UUID的前8位
    output_path = f"markdown_excel_{timestamp}_{random_id}.xlsx"
        
    # 不保存文件，返回二进制内容
    result1 = markdown_to_excel(markdown_content, output_path=None, convert_to_base64=False)
    binary_data = result1["binary_data"]  # 修改这里，使用result1而不是result
    # print("不保存文件，返回二进制内容",binary_data)
    # 不保存文件，返回Base64编码
    result2 = markdown_to_excel(markdown_content, output_path=None, convert_to_base64=True)
    base64_data = result2["base64_data"]  # 修改这里，使用result2而不是result
    # print("不保存文件，返回Base64编码",base64_data)
    markdown_content = html_to_markdown_download(base64_data)
    print(markdown_content)

# 使用示例：
